package bma.common.netty.framereader;

import org.jboss.netty.buffer.ChannelBuffer;

import bma.common.langutil.core.LinkItem;

/**
 * 协议链模型
 * 
 * @author guanzhong
 * 
 * @param <CTX_TYPE>
 */
public abstract class FrameReaderChain<CTX_TYPE> implements
		FrameReader<CTX_TYPE> {

	private LinkItem<FrameReader<CTX_TYPE>> linkHead;// head
	private transient LinkItem<FrameReader<CTX_TYPE>> current;

	public FrameReaderChain() {
		super();
	}

	/**
	 * 构造流处理
	 * 
	 * @param reader
	 */
	public void addReader(FrameReader<CTX_TYPE> reader) {
		linkHead = LinkItem.addTail(linkHead, reader);
	}

	@Override
	public RESULT process(ChannelBuffer buffer, CTX_TYPE ctx) throws Exception {

		if (current == null) {
			if (linkHead == null)
				throw new NullPointerException("FrameReader");
			current = linkHead;
		}

		while (true) {
			RESULT r = current.get().process(buffer, ctx);
			switch (r) {
			case AGAIN:
				continue;
			case NOT_DONE:
			case END:
				return r;
			case DONE:
				current = current.getNext();
				if (current == null) {
					return RESULT.END;
				}
				continue;
			}
		}
	}
}
